package xh.server.commands;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * Created by Administrator on 2016/6/25.
 */
public class PlayerOperationFactory {

    private static final String CommandsPackage = "xh.server.commands.impl";

    private static List<PlayerCommand> commands;

    static {

        List<String> classNames = getClassName(CommandsPackage);
        List<PlayerCommand> tmp = new ArrayList<PlayerCommand>();

        for (String cn : classNames) {
            try {
                Class c = Class.forName(cn);
                if (PlayerCommand.class.isAssignableFrom(c)) {
                    Object o = c.newInstance();
                    tmp.add((PlayerCommand) o);
                }
            } catch (ClassNotFoundException e) {
                continue;
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }

        commands = new ArrayList<PlayerCommand>(tmp.size());
        commands.addAll(tmp);
    }


    public static PlayerCommand create(String name) {

        PlayerOperation opt = PlayerOperation.from(name);

        if (opt == null) {
            return null;
        }

        for (PlayerCommand c : commands) {
            if (c.getPlayerOperation() == opt) {
                return c;
            }
        }

        return null;
    }


    public static List<String> getClassName(String packageName) {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();

        String packagePath = packageName.replace(".", "/");
        URL url = loader.getResource(packagePath);
        if (url == null) {
            return Collections.emptyList();
        }

        List<String> result = new ArrayList<String>();
        if (url.getProtocol().equals("file")) {
            File dir = new File(url.getPath());
            File[] classFiles = dir.listFiles(new FilenameFilter() {
                public boolean accept(File dir, String name) {
                    return name.endsWith(".class");
                }
            });

            for (File cf : classFiles) {
                result.add(packageName + "." + cf.getName().substring(0, cf.getName().indexOf(".")));
            }
        } else if (url.getProtocol().equals("jar")) {

            JarFile jar = null;
            try {
                jar = ((JarURLConnection) url.openConnection()).getJarFile();
                Enumeration<JarEntry> entries = jar.entries();
                while (entries.hasMoreElements()) {
                    JarEntry entry = entries.nextElement();
                    String name = entry.getName();
                    if (!name.startsWith(packagePath)) {
                        continue;
                    }

                    if (entry.isDirectory() || !name.endsWith(".class")) {
                        continue;
                    }

                    System.out.println(name);
                    result.add(name.substring(0, name.length() - ".class".length()).replace("/", "."));
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    jar.close();
                } catch (Exception e) {
                }
            }
        }

        return result;
    }
}
